package org.amphiprion.descentv2assistant.ui.fragment;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.amphiprion.descentv2assistant.App;
import org.amphiprion.descentv2assistant.R;
import org.amphiprion.descentv2assistant.adapter.EncounterHeroListAdapter;
import org.amphiprion.descentv2assistant.dao.db.EncounterHeroDao;
import org.amphiprion.descentv2assistant.dao.xml.ArchetypeXmlDao;
import org.amphiprion.descentv2assistant.dao.xml.ConditionXmlDao;
import org.amphiprion.descentv2assistant.dao.xml.HeroXmlDao;
import org.amphiprion.descentv2assistant.entity.Archetype;
import org.amphiprion.descentv2assistant.entity.Condition;
import org.amphiprion.descentv2assistant.entity.EncounterHero;
import org.amphiprion.descentv2assistant.entity.Hero;
import org.amphiprion.descentv2assistant.entity.comparator.EncounterHeroComparator;
import org.amphiprion.descentv2assistant.entity.comparator.HeroArchetypeComparator;
import org.amphiprion.descentv2assistant.filter.ExcludeFilter;
import org.amphiprion.descentv2assistant.filter.IncludeFilter;
import org.amphiprion.descentv2assistant.ui.popup.EncounterHeroPopupWindow;
import org.amphiprion.descentv2assistant.ui.views.PinnedHeaderListView;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

public class EncounterHeroListFragment extends SherlockFragment implements View.OnClickListener, AdapterView.OnItemClickListener {

	private boolean mActivityCreated;
	private EncounterHeroListAdapter mAdapter;
	private List<EncounterHero> mHeroes = new ArrayList();
	private PinnedHeaderListView mListView;
	private final Handler mHandler = new Handler();
	private View fragment;
	private final ExcludeFilter filter = new ExcludeFilter();

	public static EncounterHeroListFragment sThis;

	private ActionMode.Callback mActionModeCallback;
	private ActionMode mActionMode;
	private EncounterHero current;
	private int currentIndex;
	private View viewToUnselect;
	private EncounterHeroPopupWindow popup;

	public static Fragment newInstance() {
		sThis = new EncounterHeroListFragment();
		return sThis;
	}

	public void showPhotoNotePopup(EncounterHero encounterHero) {
		popup = new EncounterHeroPopupWindow(EncounterHeroListFragment.this.getSherlockActivity(), encounterHero, EncounterHeroListFragment.this.fragment);
		popup.setAnimationStyle(R.style.AnimationPopup);
		popup.show();
	}

	private void onLoadDone() {
		this.mListView.setAdapter(this.mAdapter);
		this.mListView.setOnScrollListener(this.mAdapter);
		this.mListView.setDividerHeight(0);
		this.mListView.setOnItemClickListener(this);

		this.mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> paramAnonymousAdapterView, View view, int index, long paramAnonymousLong) {
				onItemClick(paramAnonymousAdapterView, view, index, paramAnonymousLong);

				return true;
			}
		});
	}

	public void initData() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				mHeroes = EncounterHeroDao.getInstance(getActivity()).getAll(App.currentGameSession);
				Collections.sort(mHeroes, new EncounterHeroComparator());

				EncounterHeroListFragment.this.mHandler.post(new Runnable() {
					@Override
					public void run() {
						if (EncounterHeroListFragment.this.mAdapter == null) {
							mAdapter = new EncounterHeroListAdapter(getActivity(), EncounterHeroListFragment.this.mHeroes);
							EncounterHeroListFragment.this.onLoadDone();
						} else {
							EncounterHeroListFragment.this.mAdapter.setItems(EncounterHeroListFragment.this.mHeroes);
						}
						// EpisodeDiffusionListFragment.this.mAdapter.setOnSeasonWatch(EpisodeDiffusionListFragment.sThis);
					}
				});
			}
		}).start();
	}

	@Override
	public void onActivityCreated(Bundle paramBundle) {
		super.onActivityCreated(paramBundle);
		this.mActivityCreated = true;
		this.mListView.setPinnedHeaderView(LayoutInflater.from(getActivity()).inflate(R.layout.list_hero_header, this.mListView, false));

		initData();
	}

	@Override
	public void onClick(View paramView) {
		// Object localObject = paramView.getTag();
		// if ((localObject instanceof Hero)) {
		// Hero localEpisode = (Hero) localObject;
		// App.currentHero = localEpisode;
		// // TODO voir detail d'un episode
		// // this.mApp.startEpisodeActivity(getActivity(), paramView);
		// }
	}

	@Override
	public void onCreate(Bundle paramBundle) {
		super.onCreate(paramBundle);

		mActionModeCallback = new ActionMode.Callback() {

			@Override
			public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public void onDestroyActionMode(ActionMode mode) {
				mActionMode = null;
				if (viewToUnselect != null) {
					viewToUnselect.setSelected(false);
					viewToUnselect = null;
				}
			}

			@Override
			public boolean onCreateActionMode(ActionMode mode, Menu menu) {
				MenuInflater inflater = mode.getMenuInflater();
				inflater.inflate(R.menu.context_encounter_hero, menu);
				return true;
			}

			@Override
			public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
				switch (item.getItemId()) {
				case R.id.menu_add_health:
					// mode.finish(); // Action picked, so close the CAB
					current.setHealth(current.getHealth() + 1);
					// if (current.getHealth() > current.getHero().getCharacteristic().getHealth()) {
					current.setHealth(current.getHero().getCharacteristic().getHealth());
					// }
					mAdapter.setHero(currentIndex, current);
					mListView.invalidate();
					EncounterHeroDao.getInstance(getActivity()).persist(current);
					return false;
				case R.id.menu_decrease_health:
					// mode.finish(); // Action picked, so close the CAB
					if (current.getHealth() > 0) {
						current.setHealth(current.getHealth() - 1);
						mAdapter.setHero(currentIndex, current);
						mListView.invalidate();

						EncounterHeroDao.getInstance(getActivity()).persist(current);
					}
					return false;
				case R.id.menu_add_stamina:
					// mode.finish(); // Action picked, so close the CAB
					current.setStamina(current.getStamina() + 1);
					// if (current.getStamina() > current.getHero().getCharacteristic().getStamina()) {
					current.setStamina(current.getHero().getCharacteristic().getStamina());
					// }
					mAdapter.setHero(currentIndex, current);
					mListView.invalidate();
					EncounterHeroDao.getInstance(getActivity()).persist(current);
					return false;
				case R.id.menu_decrease_stamina:
					// mode.finish(); // Action picked, so close the CAB
					if (current.getStamina() > 0) {
						current.setStamina(current.getStamina() - 1);
						mAdapter.setHero(currentIndex, current);
						mListView.invalidate();
						EncounterHeroDao.getInstance(getActivity()).persist(current);
					}
					return false;
				case R.id.menu_edit_tag:
					mode.finish();

					final EditText input = new EditText(getActivity());
					if (current.getTag() != null) {
						input.setText(current.getTag());
					}
					new AlertDialog.Builder(getActivity()).setTitle("Tag").setView(input).setPositiveButton(R.string.done, new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int whichButton) {
							Editable value = input.getText();
							current.setTag(value.toString());
							EncounterHeroDao.getInstance(getActivity()).persist(current);
							mAdapter.setHero(currentIndex, current);
						}
					}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int whichButton) {
							// Do nothing.
						}
					}).show();

					return true;
				case R.id.menu_delete:
					mode.finish();
					EncounterHeroDao.getInstance(getActivity()).delete(current);
					initData();
					return true;

				case R.id.menu_add_condition:
					mode.finish();
					{
						final List<Condition> conditions = ConditionXmlDao.getInstance().getConditions();
						Collections.sort(conditions);

						final CharSequence[] items = new CharSequence[conditions.size()];
						for (int i = 0; i < conditions.size(); i++) {
							items[i] = conditions.get(i).getName();
						}
						AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
						builder.setTitle(R.string.title_activity_choose_condition);
						builder.setItems(items, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int item) {
								Condition cToAdd = conditions.get(item);
								int existsIndex = current.getConditions().indexOf(cToAdd);
								if (existsIndex != -1) {
									cToAdd = current.getConditions().get(existsIndex);
								} else {
									current.getConditions().add(cToAdd);
								}
								cToAdd.setCount(cToAdd.getCount() + 1);

								EncounterHeroDao.getInstance(getActivity()).persist(current);
								mAdapter.setHero(currentIndex, current);
							}
						});
						builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
							}
						});

						AlertDialog alert = builder.create();
						alert.show();
					}
					return true;
				case R.id.menu_remove_condition:
					if (current.getConditions().size() > 0) {
						mode.finish();
						final List<Condition> conditions = current.getConditions();

						final CharSequence[] items = new CharSequence[conditions.size()];
						for (int i = 0; i < conditions.size(); i++) {
							Condition c = conditions.get(i);
							// if (c.getCount() > 1) {
							// items[i] = c.getName() + " x" + c.getCount();
							// } else {
							items[i] = c.getName();
							// }
						}
						AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
						builder.setTitle(R.string.title_activity_remove_condition);
						builder.setItems(items, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int item) {
								Condition cToRemove = conditions.get(item);
								int existsIndex = current.getConditions().indexOf(cToRemove);
								if (existsIndex != -1) {
									cToRemove = current.getConditions().get(existsIndex);
									cToRemove.setCount(cToRemove.getCount() - 1);
									if (cToRemove.getCount() <= 0) {
										current.getConditions().remove(cToRemove);
									}
									EncounterHeroDao.getInstance(getActivity()).persist(current);
									mAdapter.setHero(currentIndex, current);
								}
							}
						});
						builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
							}
						});

						AlertDialog alert = builder.create();
						alert.show();
						return true;
					} else {
						return false;
					}
				case R.id.btPhotoNotes:
					mode.finish();
					showPhotoNotePopup(current);
					return true;
				default:
					return false;
				}
			}
		};
	}

	@Override
	public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) {
		super.onCreateView(paramLayoutInflater, paramViewGroup, paramBundle);
		this.fragment = paramLayoutInflater.inflate(R.layout.fragment_hero_list, null);
		this.mListView = ((PinnedHeaderListView) this.fragment.findViewById(R.id.heroes));
		return this.fragment;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	@Override
	public void onItemClick(AdapterView<?> paramAdapterView, View view, int index, long paramLong) {
		current = this.mHeroes.get(index);
		currentIndex = index;
		// Start the CAB using the ActionMode.Callback defined above
		mActionMode = getSherlockActivity().startActionMode(mActionModeCallback);
		view.setSelected(true);
		viewToUnselect = view;
		return;
	}

	@Override
	public void onPause() {
		super.onPause();
		// sThis = null;
	}

	@Override
	public void onResume() {
		super.onResume();
	}

	// @Override
	// public void onSeasonWatch(int serieId, String SeasonId, boolean watched) {
	// EpisodeDao.getInstance(getActivity()).watch(serieId, SeasonId, watched);
	// initData();
	// }

	public void scrollToTop() {
		this.mListView.smoothScrollToPosition(0);
	}

	public void addHero() {
		final AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
		// define the alert dialog with the choices and the action to take
		// when one of the choices is selected
		View v = LayoutInflater.from(getActivity()).inflate(R.layout.select_encounter_hero, null);
		final Spinner cbFilter = (Spinner) v.findViewById(R.id.cbFilter);
		final Spinner cbName = (Spinner) v.findViewById(R.id.cbName);

		final List<Archetype> archs = ArchetypeXmlDao.getInstance().getArchetypes();
		final IncludeFilter addFilter = new IncludeFilter();
		final List<Hero> heroesToPropose = new ArrayList<Hero>();

		cbFilter.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1, int index, long arg3) {
				addFilter.clear();
				heroesToPropose.clear();
				addFilter.checkTrait(archs.get(cbFilter.getSelectedItemPosition()).getId());
				heroesToPropose.addAll(HeroXmlDao.getInstance().getHeroes(addFilter));
				Collections.sort(heroesToPropose, new HeroArchetypeComparator());
				fillNameSpinner(cbName, heroesToPropose);
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
			}
		});

		String[] array = new String[archs.size()];
		for (int i = 0; i < archs.size(); i++) {
			array[i] = archs.get(i).getName();
		}
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, array);
		cbFilter.setAdapter(adapter);

		ad.setView(v);
		ad.setPositiveButton(R.string.done, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				Hero hero = heroesToPropose.get(cbName.getSelectedItemPosition());

				EncounterHero eh = new EncounterHero();
				eh.setGameId(App.currentGameSession.getId());
				eh.setHero(hero);
				eh.setHealth(hero.getCharacteristic().getHealth());
				eh.setStamina(hero.getCharacteristic().getStamina());
				EncounterHeroDao.getInstance(getActivity()).persist(eh);
				initData();
			}
		});
		ad.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		ad.show();
	}

	private void fillNameSpinner(Spinner cbFilter, List<Hero> names) {
		String[] array = new String[names.size()];
		for (int i = 0; i < names.size(); i++) {
			array[i] = names.get(i).getName();
		}
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, array);
		cbFilter.setAdapter(adapter);
	}

	public void photoTaken(Intent data) {
		popup.photoTaken(data);
	}

}